package kycadminrepo

import (
	"context"

	"code.bydev.io/cht/customer/kyc_admin_service/internal/pkg/helper"
	"code.bydev.io/cht/customer/kyc_admin_service/internal/pkg/kycadminrepo/o_member_kyc_readonly"
	"code.bydev.io/cht/customer/kyc_admin_service/internal/pkg/kycprovider/dto"
	"git.bybit.com/svc/dbstructure_user/pkg/o_member_kyc"
	"git.bybit.com/svc/go/pkg/bdal/bqb"
	"git.bybit.com/svc/go/pkg/bzap"
	"go.uber.org/zap"
)

var (
	SQLGetMemberKYC = o_member_kyc_readonly.Select().WhereC(func(wb *bqb.WhereBuilder) {
		o_member_kyc.FldMemberId.EQ(wb)
	}).LimitC(1).SQL()
)

func (r *repo) GetMemberKYC(ctx context.Context, memberID int64) (*dto.MemberKYC, error) {
	pool, err := r.userDB.DBDefaultMasterNodePool(ctx)
	if err != nil {
		return nil, err
	}
	record, err := o_member_kyc_readonly.ScanRecord(SQLGetMemberKYC.QueryArgs(ctx, pool, bqb.Args{
		o_member_kyc.FldMemberId.Param(): memberID,
	}))
	if err != nil {
		return nil, err
	}
	kyc := &dto.MemberKYC{
		MemberID:     int64(record.MemberId),
		Country:      record.Country,
		Level:        dto.KYCLevel(record.Level),
		Type:         dto.KYCType(record.Type),
		ReviewResult: dto.ReviewResult(record.Result),
		Limitation:   dto.Limitation(record.Limitation),
		CreateAt:     record.CreatedAt,
	}

	kyc.UnmarshalLimitation(record.LimitationInfo)
	kyc.UnmarshalDocuments(record.Documents)
	a, err := helper.DecryptStringWithBase64(record.Applicant, r.internalKey)
	if err == nil {
		kyc.UnmarshalApplicant(a)
	} else {
		bzap.LogError(r.logger, "DecryptStringWithBase64", err)
	}
	r.logger.Debug("GetMemberKYC", zap.Any("memberID", memberID), zap.Any("kyc.Applicant", kyc.Applicant))
	if kyc.Applicant != nil && kyc.Applicant.PassTime == "" {
		kyc.Applicant.PassTime = record.UpdatedAt.Format("2006-01-02 15:04:05+0000")
	}
	return kyc, nil
}

func (r *repo) GetFirstPoi(ctx context.Context, memberID int64) (*dto.Identify, error) {
	memberKyc, err := r.GetMemberKYC(ctx, memberID)
	if err != nil {
		return nil, err
	}

	if memberKyc.Applicant != nil && len(memberKyc.Applicant.Identities) > 0 {
		passedIdentity := r.getPassedIdentify(ctx, memberKyc.Applicant, memberID)
		if len(passedIdentity) > 0 {
			return passedIdentity[0], nil
		}
	}
	return nil, nil
}

func (r *repo) getPassedIdentify(ctx context.Context, applicant *dto.Applicant, memberID int64) []*dto.Identify {
	Identities := applicant.Identities
	retIdent := make([]*dto.Identify, 0)
	if len(Identities) == 0 {
		return Identities
	}
	for _, ident := range Identities {
		if ident.Type.IsValidIdentityType() {
			retIdent = append(retIdent, ident)
		}
	}
	if len(retIdent) == 1 {
		r.logger.Info("getPassIdent only one", zap.Any("uid", memberID), zap.Reflect("applicant", applicant))
		return retIdent
	}

	for _, ident := range Identities {
		if ident.Type.IsValidIdentityType() {
			if ident.Dob == applicant.Dob && ident.Country == applicant.Country && ident.Firstname == applicant.Firstname {
				retIdent = []*dto.Identify{ident}
			}
		}
	}
	if len(retIdent) == 1 {
		r.logger.Info("getPassIdent name compare", zap.Any("uid", memberID), zap.Reflect("applicant", applicant))
		return retIdent
	}
	if len(retIdent) > 0 {
		r.logger.Info("getPassIdent last", zap.Any("uid", memberID), zap.Reflect("applicant", applicant))
		return []*dto.Identify{retIdent[len(retIdent)-1]}
	}
	r.logger.Info("getPassIdent miss", zap.Any("uid", memberID), zap.Reflect("applicant", applicant))

	return []*dto.Identify{}
}
